/*
 * Copyright (c) 2022-2023 cetcclout Co., Ltd All rights reserved.
 * Sensor Adapter is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package com.cetccloud.cimp.adapter.datasource.redis.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import com.cetccloud.cimp.adapter.datasource.redis.IRedisService;
import com.cetccloud.cimp.adapter.datasource.redis.RedisService;
import com.cetccloud.cimp.adapter.handler.DataContextValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jetbrains.annotations.NotNull;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @author
 * @Description TODO 缓存操作服务
 * @Date 2022/7/8 14:03
 */
@Service
public class RedisServiceImpl implements IRedisService {
    private static final Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class);

    private static final JsonJacksonCodec JSON_JACKSON_CODEC = new JsonJacksonCodec();

    //监控仪与设备映射关系
    private static final String PREFIX_MONITOR_DEVICE = "cimp:monitor-to-device";

    public static final String JR_DEVICE_MODEL_KEY = "jr:d2m:E2MIS_%s";

    public static final String JR_MODEL_SERVER_KEY = "jr:m2s:%s";

    public static final String JR_DIS_MODEL_SCHEMA = "jr:schema:%s";
    
    private static  final String METHOD_INOUT_PROS_KEY="properties";

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    RedisService redisService;


    /**
     * 启动时候加载数据到内存
     */
    @Override
    public Map<String, String> batchGetMonitorDeviceValue() {
        return redissonClient.getMap(PREFIX_MONITOR_DEVICE, JSON_JACKSON_CODEC);
    }
    
    /**
     * 批量删除监控数据
     */
    @Override
    public void batchDeleteMonitorDeviceValue() {
        redissonClient.getMap(PREFIX_MONITOR_DEVICE, JSON_JACKSON_CODEC).delete();
    }
    
    /**
     * 设置监控数据
     */
    @Override
    public void setMonitorDeviceValue(String key, String value) {
        redissonClient.getMap(PREFIX_MONITOR_DEVICE, JSON_JACKSON_CODEC).fastPut(key, value);
    }
    
    /**
     * 删除监控仪和设备关系
     */
    @Override
    public void removeMonitorDeviceValue(String key) {
        redissonClient.getMap(PREFIX_MONITOR_DEVICE, JSON_JACKSON_CODEC).removeAsync(key);
    }

    /**
     * 获取对应模型的的参数信息
     */
    public JsonNode getCheckSchema(String modelId, String... schemaKey){

        ObjectMapper mapper = new ObjectMapper();
        JSONObject jsonSchema = getJsonSchema(modelId);
        JsonNode schemaNode = null;
        try {
            if (null == schemaKey || schemaKey.length == 0) {
                schemaNode = mapper.readTree(jsonSchema.toString());
            } else {

                JSONArray methodsSchemaArray = (JSONArray) jsonSchema.getByPath("methods");
                JSONObject method2Schema = new JSONObject();
                methodsSchemaArray.forEach(methodRow -> {
                    JSONObject mSchema = (JSONObject) methodRow;
                    mSchema.keySet().forEach(key -> {
                        method2Schema.putByPath(key, mSchema.getJSONObject(key));
                    });
                });
                jsonSchema = method2Schema;

                for (int i = 1, schemaKeyLength = schemaKey.length; i < schemaKeyLength; i++) {
                    String s = schemaKey[i];
                    jsonSchema = jsonSchema.getJSONObject(s);
                }
                schemaNode = mapper.readTree(jsonSchema.toString());
            }
            return schemaNode;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 根据设备标识获取设备所属物模型信息
     */
    @NotNull
    public JSONObject getJsonSchema(String modelId) {
        //todo test==========================================
        Object allSchema = redisService.get(String.format(JR_DIS_MODEL_SCHEMA, modelId));
        JSONObject jsonSchema = JSONUtil.parseObj(allSchema);
        return jsonSchema;
    }

    /**
     * 获取设备所属模型信息
     */
    public Object getModelByDevice(String deviceId) {
        Object modelId = redisService.get(String.format(JR_DEVICE_MODEL_KEY, deviceId));
        return modelId;
    }
    
    /**
     * 获取校验规则信息
     */
    public JsonNode getCheckSchema(String deviceId){
    	ObjectMapper mapper = new ObjectMapper();
        JsonNode schemaNode = null;
        String allSchema = (String) redisService.get(String.format(DataContextValue.DEVICE_KEY, deviceId));
        try {
			schemaNode = mapper.readTree(allSchema);
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
        return schemaNode;
    }

}
